/*
 ============================================================================
 Name        : prueba.c
 Author      : ea
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include "headers/GlobalHeader.h"
#include <pthread.h>

void thread_cliente (void *parametro);
void thread_plan (void *parametro);

int main2(void) {
	int32_t a;
	int32_t addrlen = sizeof(struct sockaddr_in);
	int32_t socket_server_pfs = socket(AF_INET,SOCK_STREAM,0);
	int32_t socket_server_ppd = socket(AF_INET,SOCK_STREAM,0);
	int32_t cliente_pfs;
	int32_t cliente_ppd;
	int descriptor_maximo;
	int yes = 1;
	int32_t raid_en_funcionamiento = 0;
	//int32_t clientes_pfs[CANT_CLIENTES_PFS_MAX];
	int32_t clientes_ppd[CANT_CLIENTES_PPD_MAX];
	int32_t cliente_pdd;
	int32_t param;
	fd_set sockets_que_espero, sockets_que_espero2;
	nipc paquete;
	struct timeval timeout;
	timeout.tv_sec = 99999;

	pthread_t thread_cliente_id = 1, thread_plan_id;
	pthread_create (&thread_cliente_id, NULL,(void*) &thread_cliente,(void *) &param);

	//inicializoArray(clientes_ppd);

	//CONFIGURACION SOCKETS
/*
		//Direccion local pfs
		struct sockaddr_in *direccion_local_pfs = malloc(addrlen);
		//Direccion remota(a la que me quiero conectar)
		struct sockaddr_in *direccion_remota_pfs = malloc(addrlen);


		direccion_local_pfs->sin_family = AF_INET;
		direccion_local_pfs->sin_addr.s_addr = inet_addr("127.0.0.1");
		direccion_local_pfs->sin_port = htons(5301);
		bind(socket_server_pfs,(struct sockaddr *)direccion_local_pfs, addrlen);
*/
		//Direccion local ppd
		struct sockaddr_in *direccion_local_ppd = malloc(addrlen);
		//Direccion remota(a la que me quiero conectar)
		struct sockaddr_in *direccion_remota_ppd = malloc(addrlen);

		direccion_local_ppd->sin_family = AF_INET;
		direccion_local_ppd->sin_addr.s_addr = inet_addr("127.0.0.1");
		direccion_local_ppd->sin_port = htons(5300);
		bind(socket_server_ppd,(struct sockaddr *)direccion_local_ppd, addrlen);

		if((listen(socket_server_ppd,1)) == -1){
			perror("listen");
			exit(1);
		}
		if (setsockopt(socket_server_ppd, SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(int)) == -1) {
			perror("setsockopt");
			exit(1);
		}
		FD_ZERO(&sockets_que_espero);
		FD_SET(socket_server_ppd,&sockets_que_espero);
		descriptor_maximo = socket_server_ppd;

		while(1){
			  sockets_que_espero2 = sockets_que_espero;
			  select(descriptor_maximo+1,&sockets_que_espero2,NULL,NULL,&timeout);
			  if(FD_ISSET(socket_server_ppd,&sockets_que_espero)){
				  cliente_ppd = accept(socket_server_ppd,(struct sockaddr *)direccion_remota_ppd,(void *)&addrlen);
				  pthread_create (&thread_plan_id, NULL,(void*) &thread_plan,(void *) &cliente_ppd);

				  //cliente_ppd = 192837;
				  //insertarEnArray(clientes_ppd,cliente_ppd);
				  //FD_SET(cliente_ppd,&sockets_que_espero);
				  //if(cliente_ppd > descriptor_maximo) descriptor_maximo = cliente_ppd;

			  }
/*			  for(a=0; a<CANT_CLIENTES_PPD_MAX; a++){
				  if(FD_ISSET (clientes_ppd[a],&sockets_que_espero)){
					  if((recv(clientes_ppd[a],&paquete,sizeof(nipc),0) > 0)){
						  if(paquete.type == 0){ //ES HANDSHAKE
							  //conexion_sincronizacion (&frente_colaGrande,&fin_colaGrande,paquete.payload.planificador_id,clientes_ppd[a]);
							  printf("%s",paquete.payload.planificador_id);
						  }
						  else{
							  //ENVIAR PAQUETE CON ERROR "NO HUBO HANDSHAKE AUN"
						  }
					  }
					  else{
						  //EL CLIENTE CERRO LA CONEXION
						  //ELIMINO CLIENTE DEL ARRAY
						  close(clientes_ppd[a]);
					  }
				  }
			  }
*/
		}

	pthread_join(thread_cliente_id,NULL);
	pthread_join(thread_plan_id,NULL);

	puts("PRUEBA SOCKETS"); /* prints PRUEBA SOCKETS */
	return EXIT_SUCCESS;
}

void thread_cliente (void *parametro){
	int32_t addrlen = sizeof(struct sockaddr_in);
	int32_t socket_cliente = socket(AF_INET,SOCK_STREAM,0);
	char carac;
	nipc paquete_mando,paquete_recibo;

	//Direccion local pfs
	struct sockaddr_in *direccion_local = malloc(addrlen);
	//Direccion remota(a la que me quiero conectar)
	struct sockaddr_in *direccion_remota = malloc(addrlen);

	direccion_local->sin_family = AF_INET;
	direccion_local->sin_addr.s_addr = INADDR_ANY;
	direccion_local->sin_port = htons(5301);
	bind(socket_cliente,(struct sockaddr *)direccion_local, addrlen);

	direccion_remota->sin_family = AF_INET;
	direccion_remota->sin_addr.s_addr = inet_addr("127.0.0.1");
	direccion_remota->sin_port = htons(5300);

	carac = getchar();

	connect(socket_cliente,(struct sockaddr *)direccion_remota,addrlen);

	paquete_mando.type = 0;
	strcpy(paquete_mando.payload.planificador_id,"ppd_eabutti");
	if((send(socket_cliente,&paquete_mando,sizeof(nipc),0)) <= 0){
		perror("send");
	}

	if((recv(socket_cliente,&paquete_recibo,sizeof(nipc),0)) <= 0) {
		perror("recv");
		exit (1);
	}

	if(paquete_recibo.payloadlength == 0){
		while(1){
			recv(socket_cliente,&paquete_recibo,sizeof(nipc),0);
			printf("sector pedido: %i \n",paquete_recibo.payload.direccionSector);
			paquete_mando.type = 12;
			strcpy(paquete_mando.payload.info,"info1");
			//paquete_mando.payload.pedido_id = 227;
			send(socket_cliente,&paquete_mando,sizeof(nipc),0);
		}
	}
	return;
}
void thread_plan (void *parametro){
	int32_t socket_ppd = *(int32_t *) parametro, hand_ok = 0;
	nipc paquete_recibo, paquete_mando;
	char carac;

	recv(socket_ppd,&paquete_recibo,sizeof(nipc),0);

	if(paquete_recibo.type == 0){ //ES HANDSHAKE
		hand_ok = 1;
		printf("nombre ppd: %s \n",paquete_recibo.payload.planificador_id);
		paquete_mando.type = 0;
		paquete_mando.payloadlength = 0;
		strcpy(paquete_mando.payload.info,"hand ok");
		send(socket_ppd,&paquete_mando,sizeof(nipc),0);
	}
	if(hand_ok == 1){
		carac = getchar();
		paquete_mando.type = 1;
		paquete_mando.payload.direccionSector = 555;
		send(socket_ppd,&paquete_mando,sizeof(nipc),0);
	}
	recv(socket_ppd,&paquete_recibo,sizeof(nipc),0);
	//if(paquete_recibo.type == 12){
	printf("Ya tengo la info del pedido");
	//}
	sleep(1);
	return;
}
